package com.hongye.proprietary.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.hongye.common.utils.R;
import com.hongye.proprietary.entity.AgentUserEntity;
import com.hongye.proprietary.entity.GroupBuyingEntity;
import com.hongye.proprietary.entity.UserHomeEntity;
import com.hongye.proprietary.service.GroupBuyingService;
import com.sun.org.apache.regexp.internal.RE;
import org.redisson.api.RLock;
import org.redisson.api.RReadWriteLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.TimeUnit;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hongye.common.utils.PageUtils;
import com.hongye.common.utils.Query;

import com.hongye.proprietary.dao.GroupUserRelationshipDao;
import com.hongye.proprietary.entity.GroupUserRelationshipEntity;
import com.hongye.proprietary.service.GroupUserRelationshipService;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpSession;
import javax.validation.constraints.Future;


@Service("groupUserRelationshipService")
public class GroupUserRelationshipServiceImpl extends ServiceImpl<GroupUserRelationshipDao, GroupUserRelationshipEntity> implements GroupUserRelationshipService {

    @Autowired
    RedissonClient redissonClient;
    @Autowired
    StringRedisTemplate redisTemplate;

    @Autowired
    GroupBuyingService groupBuyingService;
    @SuppressWarnings("all")
    @Autowired
    GroupUserRelationshipDao groupUserRelationshipDao;


    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<GroupUserRelationshipEntity> page = this.page(
                new Query<GroupUserRelationshipEntity>().getPage(params),
                new QueryWrapper<GroupUserRelationshipEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public R signup(GroupUserRelationshipEntity groupUserRelationship, HttpSession session) {
        //分布式锁
        RLock lock = redissonClient.getLock("groupbuy-lock" + groupUserRelationship.getGroupBuyId());
        boolean islock;
        try {
            islock=lock.tryLock(3,10,TimeUnit.SECONDS);
            if(!islock) return R.error("系统繁忙，请稍后重试。");
            //根据中间表得团购表id去查团购表得状态
            GroupBuyingEntity groupBuyingEntity = groupBuyingService.getById(groupUserRelationship.getGroupBuyId());
            if (groupBuyingEntity==null)  return R.error("团购数据获取有误，无法报名。");
            if (groupBuyingEntity.getGroupBuyingStatus()==1)  return R.error("团购已开始，无法报名");
            if (groupBuyingEntity.getGroupBuyingEnddate().compareTo(new Date()) < 0) return R.error("报名时间已过期，无法报名");
            //通过中间表查询人数
            Integer peoplesum=groupUserRelationshipDao.selpeoplesum(groupUserRelationship.getGroupBuyId());
            //通过团购表查询最大报名人数
            if (peoplesum>=30) return R.error("人数已满，无法报名");
            //TODO 报名代码
            //根据session获取当前登录人的id
            Object agentlogin = session.getAttribute("userlogin");
            String s = JSON.toJSONString(agentlogin);
            UserHomeEntity userHomeEntity = JSON.parseObject(s, new TypeReference<UserHomeEntity>() {
            });
            Integer agentId = userHomeEntity.getUserId();
            //去数据库查当前人有没有报名过
            Integer seleuserid = baseMapper.seleuserid(agentId);
            if (agentId.equals(seleuserid))return R.error("已报名，请勿重复报名");
            //获取到当前用户id后 插入中间表
            groupUserRelationship.setUserId(agentId);
            //获取当前团购表id插入中间表
            groupUserRelationship.setGroupBuyId(groupUserRelationship.getGroupBuyId());
            //把获取的用户和团购表的id添加到中间表
            baseMapper.insert(groupUserRelationship);
            return R.ok("报名成功").put("data",groupUserRelationship);
        }catch (Exception e){
            log.error(e.getMessage());
        }finally {
            //解锁
            lock.unlock();
        }

        /*
        //根据中间表得团购表id去查团购表得状态
        GroupBuyingEntity byId = groupBuyingService.getById(groupUserRelationship.getGroupBuyId());
        //判断
        if (byId.getGroupBuyingStatus()==0){
            RReadWriteLock readWriteLock = redissonClient.getReadWriteLock("groupbuy-lock");
            RLock readLock = readWriteLock.readLock();
            RLock writeLock = readWriteLock.writeLock();
            BoundHashOperations<String, Object, Object> ops = redisTemplate.boundHashOps("GROUPBUY:" + groupUserRelationship.getGroupBuyId().toString());
            String s="";
            //List<UserHomeEntity> userHomeEntities = new ArrayList<>();
            try {
                readLock.lock(30,TimeUnit.SECONDS);
                System.out.println("读加锁成功"+Thread.currentThread().getId());
                s = (String) ops.get(groupUserRelationship.getUserId().toString());
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                readLock.unlock();
            }
            if (!StringUtils.isEmpty(s)){
                ArrayList<String> list = new ArrayList<>();
                ops.keys().forEach(a ->{
                    list.add(JSONObject.toJSONString(a));
                });
                if (list.size()>=30) {
                    return R.error("缓存命中....,人数报满");
                } else {
                    return R.error("您已报名了");
                }
            }else {
                writeLock.lock(5,TimeUnit.SECONDS);
                ArrayList<String> list = new ArrayList<>();
                ops.keys().forEach(a ->{
                    list.add(JSONObject.toJSONString(a));
                });
                if (list.size()>=30) {
                    return R.error("缓存命中....,人数报满");
                } else {
                    try {
                        ozps.put(groupUserRelationship.getUserId().toString(),groupUserRelationship.getUserId().toString());
                    } catch (Exception e) {
                        e.printStackTrace();
                    } finally {
                        writeLock.unlock();
                    }
                }
            }

            baseMapper.insert(groupUserRelationship);
            return R.ok("报名成功");
        }
        return R.error("已经开团了，无法报名");*/
        return R.error("报名失败");
    }

}
